/**
 * 一、无畏并发
 * 1.并发(concurrent)和并行(parallel)的区别. 前者是不同程序相互独立运行，强调独立;并行则是不同程序同时运行，强调同时.
 *   但事实上，并发也由同时的概念。
 * 2.所有权和类型系统是一系列解决内存安全 和 并发问题的强有力的工具！通过利用所有权和类型检查，在 Rust 中很多并发错误都是 编译时 错误，而非运行时错误
 * 3.可以在开发时修复代码，而不是在部署到生产环境后修复代码  -- 这就是无畏并发(fearless concurrency)的由来。 这是
 *   rust的所有权和类型系统检查所带来的好处。
 * 4.rust认为所有权系统和类型检查那么重要，而这是导致它的代码特别难于阅读和理解的缘故
 * 
 * 二、rust的并发工具
 * 期望提供在任何给定的情况下有着最高的性能且对硬件有更少的抽象
 * 1.如何创建线程来同时运行多段代码。
 * 2.消息传递（Message passing）并发，其中信道（channel）被用来在线程间传递消息。
 * 3.共享状态（Shared state）并发，其中多个线程可以访问同一片数据。
 * 4.Sync 和 Send trait，将 Rust 的并发保证扩展到用户定义的以及标准库提供的类型中。
 * 
 * 三、同时运行线程
 * 1.使用thread::spawn函数创建线程，它会返回一个JoinHandle<T>智能指针。
 * 2.如果没有特别措施，那么当主线程结束的时候，也会强制结束其它线程，这个需要特别注意。所以现实中很少会这么使用子线程
 * 3.使用JoinHandle<T>智能指针的join方法，可以等待子线程结束。 但如果仅仅这么做，那么会导致主线程阻塞，直到子线程结束。
 *   所以，光光这样，并不会真正地并发.
 *   如果只是一个主线程，一个子线程，那么先运行主线程，再使用子线程的join,那么可以保证并发，且都能运行完成
 *   但如果是一个主线程，多个子线程，那么多个子线程之间就无法真正并发了。
 * 4. 利用匿名函数+move关键字，可以将变量所有权转移给子线程。但是如何共享所有权，不是仅仅靠这个措施就可以的.
 *   匿名函数对于并发还是有一定重要性的，这是因为简化的代码的编写。如果你不习惯这样，也可以的。rust也由提供响应的解决方案.
 * 
 */

 //主要示例 -- 一个主线程，一个子线程的并发，不涉及到变量的修改.
 //这里不得不使用move关键字，因为匿名函数捕获了v的引用,且必须占有所有权，否则编译报错


 use std::thread;
 use std::time::Duration;
 fn main() {
    let v = vec![1, 2, 3,4,5,6,7,8,9,10];
    let handle = thread::spawn(move ||->Vec<i32> {    //如果这里不添加move关键字，编译会报错
        println!("Here's a vector: {:?}",v);
        //循环v,每次等待50毫秒
        for i in v.iter() {
            println!("T-1-waiting...:{}  ***(^^)",i);
            thread::sleep(Duration::from_millis(50));
        }
        v
    });

    //循环10次，每次等待20毫秒
    for x in 0..10 {
        println!("T-0-waiting...:{}",x);
        thread::sleep(Duration::from_millis(20));
    }
    let p=handle.join().unwrap();
    println!("It's back!{:?}",p);
}


